<script setup>
import { useEventListener } from '@vueuse/core/index'
import useChannel from '@/store/channel'
import useUser from '@/store/user'
import useEventBus from '@/use/use-event-bus'
import { ElMessageBox } from 'element-plus'
import {
  collectMessage,
  deleteMemberMsg,
  deleteMessage,
  fixedMessagePin,
  getCollectList,
  getPinMessageList,
  markTagMsg,
  markTopMessage,
  unfixedMessagePin,
  unmarkTagMsg,
} from '@/assets/api/message'
import CancelPinDialog from '@/components/CancelPinDialog.vue'
import { useArrayDifference } from '@vueuse/core'

const props = defineProps({
  modelValue: Boolean,
  disabledContextmenu: [Boolean, Array],
  message: Object,
  position: Object,
  isRecall: Boolean,
})
const emit = defineEmits(['update:modelValue', 'forward', 'multipleChoice', 'openPinMsgDialog', 'edit'])

const channelStore = useChannel()
const userStore = useUser()
const eventBus = useEventBus()

const elRef = ref()
const contextmenuDefault = reactive(['copy', 'top', 'withdraw', 'forward', 'del', 'pin', 'collect'])

const contextmenuList = computed(() => {
  if (props.disabledContextmenu === false) {
    return contextmenuDefault
  }
  if (props.disabledContextmenu === true) {
    return []
  }
  return useArrayDifference(contextmenuDefault, props.disabledContextmenu).value
})

const isCurrentUser = computed(() => {
  return props.message?.userId === userStore.userId
})

let copyText = ''
eventBus.on('getCopyText', async (cb) => {
  cb(navigator.clipboard ? await navigator.clipboard.readText() : copyText)
})

// 复制
function copy() {
  if (navigator.clipboard) {
    navigator.clipboard.writeText(props.message.content)
  }
  copyText = props.message.content
}

// 撤回
function withdraw() {
  deleteMessage(props.message.id)
}

// 置顶
function topMessage(message) {
  markTopMessage(message.id)
}

// 删除
function remove() {
  ElMessageBox.confirm('确认删除此消息么?', '删除确认').then(() => {
    if (props.message.id) {
      deleteMemberMsg(props.message.id).then((res) => {
        if (res.code === 200) {
          channelStore.removeMessage(props.message)
        }
      })
    } else {
      channelStore.removeMessage(props.message)
    }
  })
}

// 标记
function markTag(message) {
  ;(message.metaData.status.tagFlag ? unmarkTagMsg : markTagMsg)(message.id)
  channelStore.updateMessage(message, 'metaData.status.tagFlag', !message.metaData.status.tagFlag)
}

// pin 固定消息
const cancelPinRef = ref()
function pin(message) {
  if (message.metaData.status.pinnedFlag) {
    cancelPinRef.value.open()
  } else {
    fixedMessagePin(message.id).then((res) => {
      if (res.code === 200) {
        getPinMessageList({
          channelId: message.channelId,
        }).then((res) => {
          if (res.code === 200) {
            eventBus.emit('updatePinMsgPanel', res.data)
          }
        })
      }
    })
    channelStore.updateMessage(message, 'metaData.status.pinnedFlag', !message.metaData.status.pinnedFlag)
  }
}

// 取消固定
function removePinMsg(dataVal) {
  unfixedMessagePin(dataVal.id).then((res) => {
    if (res.code === 200) {
      getPinMessageList({
        channelId: dataVal.channelId,
      }).then((res) => {
        if (res.code === 200) {
          eventBus.emit('updatePinMsgPanel', res.data)
        }
      })
    }
  })
  channelStore.updateMessage(dataVal, 'metaData.status.pinnedFlag', !dataVal.metaData.status.pinnedFlag)
}

// 收藏
function collect(message) {
  collectMessage(message.id).then((res) => {
    if (res.code === 200) {
      getCollectList().then((res) => {
        if (res.code === 200) {
          // channelStore.updateCollectList(res.data)
          eventBus.emit('updateCollectPanel', res.data)
        }
      })
    }
  })
}

onMounted(() => {
  useEventListener('click', () => {
    emit('update:modelValue', false)
  })
})

function authority(type) {
  return contextmenuList.value.includes(type)
}

// 是否是卡片消息
const isCard = computed(() => {
  return props.message?.metaData.cardInfo
})

defineExpose({
  el: elRef,
})
</script>

<template>
  <Teleport v-if="!props.disabledContextmenu || props.disabledContextmenu.length" to="body">
    <div v-show="props.modelValue" ref="elRef" class="message-contextmenu" :style="props.position">
      <div class="menu-item-box" :class="!isCard ? 'active' : ''">
        <div v-if="authority('copy') && !isCard" class="menu-item" @click="copy">
          <SvgIcon name="im-msg-copy" size="12"></SvgIcon>
          复制
        </div>
      </div>
      <div class="menu-item-box" :class="!props.message?.metaData.count.replyCount || !isCard ? 'active' : ''">
        <div v-if="authority('forward') && !isCard" class="menu-item" @click="emit('forward')">
          <SvgIcon name="im-msg-forward" size="12"></SvgIcon>
          转发
        </div>
      </div>
      <div class="menu-item-box" :class="isCurrentUser || props.isRecall || !isCard ? 'active' : ''">
        <div
          v-if="authority('withdraw') && !isCard && isCurrentUser && props.isRecall"
          class="menu-item"
          @click="withdraw">
          <SvgIcon name="im-msg-withdraw" size="12"></SvgIcon>
          撤回
        </div>
        <div v-if="authority('forward') && !isCard" class="menu-item" @click="emit('multipleChoice')">
          <SvgIcon name="im-msg-multiple" size="12"></SvgIcon>
          多选
        </div>
      </div>
      <div class="menu-item-box active">
        <div v-if="authority('withdraw')" class="menu-item" @click="markTag(props.message)">
          <SvgIcon
            :name="props.message?.metaData.status.tagFlag ? 'im-msg-cancel-flag' : 'im-msg-flag'"
            size="12"></SvgIcon>
          {{ props.message?.metaData.status.tagFlag ? '取消标记' : '标记' }}
        </div>
        <div v-if="authority('collect')" class="menu-item" @click="collect(props.message)">
          <SvgIcon name="im-msg-collect" size="12"></SvgIcon>
          收藏
        </div>
      </div>
      <div
        class="menu-item-box"
        :class="!isCard && (!channelStore.dialogExt.ownerTopMsgFlag || channelStore.isManager) ? 'active' : ''">
        <div v-if="authority('pin')" class="menu-item" @click="pin(props.message)">
          <SvgIcon
            :name="props.message?.metaData.status.pinnedFlag ? 'im-msg-unpin' : 'im-msg-pin'"
            size="12"></SvgIcon>
          {{ props.message?.metaData.status.pinnedFlag ? '取消pin' : 'pin' }}
        </div>
        <div
          v-if="authority('top') && !isCard && (!channelStore.dialogExt.ownerTopMsgFlag || channelStore.isManager)"
          class="menu-item"
          @click="topMessage(props.message)">
          <SvgIcon name="im-msg-top-message" size="12"></SvgIcon>
          置顶消息
        </div>
      </div>
      <div class="menu-item-box active">
        <div v-if="authority('del')" class="menu-item" @click="remove">
          <SvgIcon name="im-msg-remove" size="12"></SvgIcon>
          删除
        </div>
      </div>
    </div>
  </Teleport>
  <CancelPinDialog
    ref="cancelPinRef"
    :message="props.message"
    @removePinMsg="removePinMsg"
    @openPinMsgDialog="emit('openPinMsgDialog', props.message)"></CancelPinDialog>
</template>

<style lang="scss">
.message-contextmenu {
  position: absolute;
  font-size: 12px;
  padding: 5px;
  width: 150px;
  border: 1px solid #d5d5d5;
  border-radius: 5px;
  background-color: var(--elp-bg-color);
  box-shadow: var(--elp-box-shadow);
  z-index: 3;
  .menu-item-box {
    .menu-item {
      cursor: pointer;
      padding: 5px 10px;
      border-radius: 5px;
      &:hover {
        background-color: rgba(212, 216, 224, 0.5);
      }
      .svg-icon {
        color: var(--elp-text-color-primary);
        margin-right: 3px;
      }
    }
  }
  .active {
    border-bottom: 1px solid #dcdfe6;
    &:last-child {
      border-bottom: none;
    }
  }
  .el-divider--horizontal {
    margin: 5px 0;
  }
}
</style>
